/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "GameObjectManager.h"
#include "SceneObject.h"

namespace PQEngine
{
	GameObjectManager::GameObjectManager(SceneObject* sceneObject)
		: _sceneObject(sceneObject),_maxFrameObject(false),_sceneMgr(0),_selectedObject(0)
	{
		assert(_sceneObject);
		_sceneMgr=_sceneObject->getSceneManager();

		_selectMeshData=new MeshData();

		// Create RaySceneQuery for select object
		_raySceneQuery = _sceneMgr->createRayQuery(Ogre::Ray());
		_raySceneQuery->setQueryTypeMask(Ogre::SceneManager::ENTITY_TYPE_MASK);
		_raySceneQuery->setSortByDistance(true);
	}

	void GameObjectManager::createDefaultGameObjects()
	{
		
	}

	void GameObjectManager::loadGameObjects()
	{
		
	}

	void GameObjectManager::parentTo(GameObject* child,GameObject* parent)
	{
		if(child->getParent()){
			Ogre::SceneNode* childSceneNode=child->getSceneNode();
			childSceneNode->getParentSceneNode()->removeChild(childSceneNode);

			Ogre::SceneNode* parentSceneNode=parent->getSceneNode();
			parentSceneNode->addChild(childSceneNode);

			child->getParent()->removeChild(child);
			parent->addChild(child);
		}
	}

	GameObject* GameObjectManager::getRootGameObject()
	{
		return 0;
	}

	

	GameObject* GameObjectManager::selectObject(int x,int y)
	{
		if(_selectedObject){
			_selectedObject->selectObject(false);
		}
		_selectedObject=0;

		Ogre::Ray ray = _sceneObject->getRay(x,y);
		_selectedObject= getObject(ray);
		if(_selectedObject){
			_selectedObject->selectObject(true);
		}

		return _selectedObject;
	}

	GameObject* GameObjectManager::getObject(int x,int y)
	{
		GameObject* object=0;
		Ogre::Ray ray = _sceneObject->getRay(x,y);
		object= getObject(ray);
		return object;
	}


	GameObject* GameObjectManager::getObject(Ogre::Ray mouseRay)
	{
		GameObject* obj=0;
        _raySceneQuery->setRay(mouseRay);
		//OGRE sort query by distance already
		_raySceneQuery->setSortByDistance(true);
        // Execute query
		Ogre::RaySceneQueryResult &result = _raySceneQuery->execute();
        Ogre::RaySceneQueryResult::iterator itr = result.begin();
		
		 // loop through the results
		for(; itr!=result.end(); itr++){
			 if (itr->movable){
				 Ogre::SceneNode* node= itr->movable->getParentSceneNode();
				 if(itr->movable->getMovableType().compare("Entity")==0){
					Ogre::Entity* entity=static_cast<Ogre::Entity*>(itr->movable);

					_selectMeshData->loadMeshEntity(entity,node);
					if(_selectMeshData->intersect(mouseRay)){
						obj=GameObject::get(node);
						if(obj){//find and return
							  return obj;
						}
					}
				}
			 }
		 }
		
		return obj;
	}

	GameObject* GameObjectManager::getSelectedObject()
	{
		return _selectedObject;
	}

	void GameObjectManager::update(float deltaT)
	{
		
		_sceneObject->getRootGameObject()->update(deltaT);
	}

	
	void GameObjectManager::deleteGameObject()
	{
		if(_selectedObject){
			
		}
	}
	
	
}
